package com.etalk.crm.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.etalk.crm.dao.QuestionMapper;
import com.etalk.crm.dao.TextBooksMapper;
import com.etalk.crm.pojo.*;
import com.etalk.crm.service.QuestionService;
import com.etalk.crm.service.TextbooksService;
import com.etalk.crm.utils.CrmUtils;
import com.etalk.crm.utils.ExcelImportUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import static java.util.stream.Collectors.toList;
import static org.apache.poi.ss.usermodel.Cell.*;

/**
 * @author Terwer
 * @since 2018/05/23
 */
@Service
public class QuestionServiceImpl implements QuestionService {
    private static final Logger logger = LogManager.getLogger(QuestionServiceImpl.class);

    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private TextBooksMapper textBooksMapper;
    @Resource
    private TextbooksService textbooksService;

    @Override
    public PageInfo<QuestionBanks> getQuestionList(Map<String, Object> paramMap, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<QuestionBanks> list = questionMapper.selectQuestionList(paramMap);
        // 分页信息
        PageInfo<QuestionBanks> pageInfo = new PageInfo<QuestionBanks>(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        pageNum = pageInfo.getPageNum();
        pageSize = pageInfo.getPageSize();
        logger.info("分页信息：total=" + total + "，pages=" + pages + "，pageNum=" + pageNum + "，pageSize=" + pageSize + "，搜索条件：paramMap=" + JSON.toJSONString(paramMap));
        return pageInfo;
    }

    @Override
    public PageInfo<QuestionBanks> selectByGradeAndKnowledge(Integer qgradeId, Integer qknowledgeId, Integer pageNum,
                                                             Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<QuestionBanks> list = questionMapper.selectByGradeAndKnowledge(qgradeId, qknowledgeId);
        // 分页信息
        PageInfo<QuestionBanks> pageInfo = new PageInfo<QuestionBanks>(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        pageNum = pageInfo.getPageNum();
        pageSize = pageInfo.getPageSize();
        logger.info("分页信息：total=" + total + "，pages=" + pages + "，pageNum=" + pageNum + "，pageSize=" + pageSize + "，搜索关键字：qgradeId=" + qgradeId + "，qknowledgeId=" + qknowledgeId);
        return pageInfo;
    }

    @Override
    public QuestionBanks selectByQuestionId(Integer questionId) {
        return selectByQuestionIdAndScoreId(questionId, 0);
    }

    @Override
    public QuestionBanks selectByQuestionIdAndScoreId(Integer questionId, Integer scoreId) {
        // 当前题目
        QuestionBanks questionBanks = questionMapper.selectByQuestionId(questionId, scoreId);
        // 设置属性
        QuestionBanks detailedQuestionBanks = initQuestionBanks(questionBanks, scoreId);

        // 设置子题目
        // 子题目（不包括图片选项答案）
        logger.info("父题目ID为：" + questionBanks.getId());
        List<QuestionBanks> subQuestions = questionMapper.selectChild(questionBanks.getId(), scoreId);
        // 子题目（添加图片选项答案）
        List<QuestionBanks> sub = null;
        // 如果有子题
        if (!CollectionUtils.isEmpty(subQuestions)) {
            List<String> underList = new ArrayList<>();
            logger.info("题目ID为：" + questionBanks.getId() + "的子题目个数：" + subQuestions.size());
            // 设置子题目
            sub = new ArrayList<>();
            for (QuestionBanks item : subQuestions) {
                QuestionBanks subItem = initQuestionBanks(item, scoreId);
                sub.add(subItem);
                // 子题目是否已经掌握
                if (null != item.getIsUnderStand()) {
                    underList.add(item.getIsUnderStand());
                }
            }
            // 外部
            String joinedUnderStr = StringUtils.join(underList.toArray(), ",");
            detailedQuestionBanks.setIsUnderStand(joinedUnderStr);
        }
        detailedQuestionBanks.setListQuestionBanks(sub);

        return detailedQuestionBanks;
    }

    /**
     * 设置题目详情
     *
     * @param questionBanks 题目
     * @return 题目详情
     */
    @Override
    public QuestionBanks initQuestionBanks(QuestionBanks questionBanks, Integer scoreId) {
        if (null == questionBanks) {
            return questionBanks;
        }
        // 图片
        List<QuestionBanksImg> questionBanksImgs = new ArrayList<>();
        List<QuestionBanksImg> imgList = questionMapper.selectQuestionBanksImgByQuestionId(questionBanks.getId());
        // 空图片不展示
        for (QuestionBanksImg img : imgList) {
            if (!StringUtils.isEmpty(img.getImgUrl())) {
                questionBanksImgs.add(img);
            }
        }
        questionBanks.setListQuestionBanksImg(questionBanksImgs);

        // 正确答案
        List<QuestionRightAnswer> questionRightAnswerList = questionMapper.selectQuestionRightAnswerByQuestionId(questionBanks.getId());
        questionBanks.setListRightAnswer(questionRightAnswerList);

        // 经过筛选的正确答案
        List<FilterdQuestionRightAnswer> filteredQuestionRightAnswerList = new ArrayList<>();
        for (QuestionRightAnswer rightAnswer : questionRightAnswerList) {
            FilterdQuestionRightAnswer filtedAnswer = new FilterdQuestionRightAnswer();
            filtedAnswer.setQbankId(rightAnswer.getQbankId());

            String filterAnswer = null;
            if (!StringUtils.isEmpty(CrmUtils.filterAnswer(rightAnswer.getAnswer1()))) {
                filterAnswer = CrmUtils.filterAnswer(rightAnswer.getAnswer1());
            } else if (!StringUtils.isEmpty(CrmUtils.filterAnswer(rightAnswer.getAnswer2()))) {
                filterAnswer = CrmUtils.filterAnswer(rightAnswer.getAnswer2());
            } else if (!StringUtils.isEmpty(CrmUtils.filterAnswer(rightAnswer.getAnswer3()))) {
                filterAnswer = CrmUtils.filterAnswer(rightAnswer.getAnswer3());
            } else {
                filterAnswer = CrmUtils.filterAnswer(rightAnswer.getAnswer4());
            }

            filtedAnswer.setAnswer(filterAnswer);
            filteredQuestionRightAnswerList.add(filtedAnswer);
        }
        questionBanks.setListFiltedRightAnswer(filteredQuestionRightAnswerList);

        // 选项
        List<QuestionOptionAnswer> questionOptionAnswerList = questionMapper.selectQuestionOptionAnswerByQuestionId(questionBanks.getId());
        questionBanks.setListOptionAnswer(questionOptionAnswerList);

        //学生填写的答案
        if (scoreId > 0) {
            List<QuestionInputAnswer> questionInputAnswerList = questionMapper.selectInputAnswerByScoreIdAndQbankId(scoreId, questionBanks.getId());
//            for (QuestionInputAnswer inputAnswer : questionInputAnswerList) {
//                inputAnswer.setInputAnswer(filterAnswer(inputAnswer.getInputAnswer()));
//            }
            questionBanks.setListInputAnswer(questionInputAnswerList);
        }
        //解析
        List<QuestionExplain> questionExplainList = questionMapper.selectQuestionExplainByQuestionId(questionBanks.getId());
        if (questionExplainList.size() > 0) {
            questionBanks.setQuestionExplain(questionExplainList.get(0));
        }

        // 知识点
        List<QuestionKnowledge> listQuestionKnowledge = questionMapper.getKnowledgeListByQuestionId(questionBanks.getId());
        questionBanks.setListQuestionKnowledge(listQuestionKnowledge);
        return questionBanks;
    }

    @Override
    public List<QuestionGrade> selectQGradeList() {
        return questionMapper.selectQGradeList();
    }

    @Override
    public List<QuestionTypes> selectQTypesList() {
        return questionMapper.selectQTypesList();
    }

    @Override
    public List<QuestionMode> selectQModeList() {
        return questionMapper.selectQModeList();
    }

    @Override
    public List<QuestionDifficultyDegree> selectQDifficultyDegreeList() {
        return questionMapper.selectQDifficultyDegreeList();
    }

    @Transactional
    @Override
    public boolean deleteByQuestionId(Integer questionId) {
        int count = questionMapper.deleteByQuestionId(questionId);
        if (count > 0) {
            questionMapper.deleteQuestionBanksImg(questionId);
            questionMapper.deleteQuestionOptionAnswer(questionId);
            questionMapper.deleteQuestionRightAnswer(questionId);
            questionMapper.deleteByQuestionId(questionId);
            // 删除知识点关联
            questionMapper.deleteRelatedKnowledgeByQuestionId(questionId);
            // 删除小题
            questionMapper.deleteSubQuestionsByQuestionId(questionId);
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public boolean saveQuestionBank(QuestionBanks questionBanks) {
        int count = questionMapper.saveQuestionBank(questionBanks);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public Integer batchSaveQuestion(List<QuestionBanks> questionBanksList, String recorder) {

        List<Integer> qids = new ArrayList<>();
        if (questionBanksList.get(0).getId() != null && questionBanksList.get(0).getId() > 0) {
            qids = questionMapper.selectIdsByParentId(questionBanksList.get(0).getId());
        }

        // 批量操作，id>0为修改，否则为新增
        for (QuestionBanks questionBanks : questionBanksList) {
            Integer questionId = questionBanks.getId();

            //设置错词本最后一级分类
            List<Integer> childMistakeIdList = questionBanks.getChildMistakeId();
            if (!CollectionUtils.isEmpty(childMistakeIdList)) {
                //最大的必然是最后一级的
                questionBanks.setMistakeId(Collections.max(childMistakeIdList));
                logger.debug("最后一级的错词本ID：questionBanks.getMistakeId()=" + questionBanks.getMistakeId());
            }

            // 不是第一个的话，设置父ID
            if (questionBanksList.get(0).getId() == null || questionBanksList.get(0).getId() == 0) {
                // 默认第一级题目的parentid为0
                questionBanks.setParentid(0);
            } else {
                logger.info("当前不是第一个");
                if (questionId==null || !questionId.equals(questionBanksList.get(0).getId())) {
                    questionBanks.setParentid(questionBanksList.get(0).getId());
                    logger.info("获取父ID：ID=" + questionBanksList.get(0).getId());

                    if (questionId != null && questionId > 0 && questionBanksList.get(0).getInputType() == QuestionBanks.INPIY_TYPE_SUB) {
                        if (qids.contains(questionId)) {
                            //排除已经有的
                            logger.info("排除已经有的：questionId=" + questionId);
                            qids.remove(questionId);
                        } else {
                            logger.info("需要添加：questionId=" + questionId);
                        }
                    }
                }
            }

            if (questionId != null && questionId > 0) {
                logger.info("修改题目：ID=" + questionId);
                questionMapper.updateQuestionBank(questionBanks);
            } else {
                logger.info("添加题目");
                questionMapper.saveQuestionBank(questionBanks);
                // 获取刚刚插入的题目ID
                questionId = questionBanks.getId();
                logger.info("刚刚插入成功新题目：ID=" + questionId);
            }

            //知识点处理（主题目才有）
            if (null != questionBanks.getRelatedKnowledge()) {
                //先删除所有的关联，然后再添加
                //删除所有的关联
                questionMapper.deleteRelatedKnowledgeByQuestionId(questionId);
                //再添加
                List<Map> knowledgeList = new ArrayList<>();
                List<Integer> knowledgeIds = questionBanks.getRelatedKnowledge();
                if (knowledgeIds.size() > 0) {
                    for (Integer knowledgeId : knowledgeIds) {
                        Map questionMap = new HashMap();
                        questionMap.put("qbankId", questionId);
                        questionMap.put("qknowledgeId", knowledgeId);
                        questionMap.put("kpMistakeId", questionBanks.getMistakeId());
                        questionMap.put("recorder", recorder);
                        knowledgeList.add(questionMap);
                    }
                    questionMapper.batchSaveQuestionBanksKnowledge(knowledgeList);
                }
            }

            // 图片处理
            questionBanks.initQuestionImgs();
            questionMapper.deleteQuestionBanksImg(questionId);
            if (!CollectionUtils.isEmpty(questionBanks.getListQuestionBanksImg())) {
                questionMapper.batchSaveQuestionImg(questionBanks.getListQuestionBanksImg());
            }

            // 选项处理
            // 初始化选项及正确答案
            questionBanks.initListOptionAnswer();
            questionMapper.deleteQuestionOptionAnswer(questionId);
            if (!CollectionUtils.isEmpty(questionBanks.getListOptionAnswer())) {
                questionMapper.batchSaveQuestionOptionAnswer(questionBanks.getListOptionAnswer());
            }

            // 答案处理
            questionMapper.deleteQuestionRightAnswer(questionId);
            if (!CollectionUtils.isEmpty(questionBanks.getListRightAnswer())) {
                questionMapper.batchSaveQuestionRightAnswer(questionBanks.getListRightAnswer());
            }

            //标签处理
            questionBanks.initListQuestionTag();
            questionMapper.deleteQuestionTag(questionId);
            if (!CollectionUtils.isEmpty(questionBanks.getListQuestionTag())) {
                questionMapper.batchSaveQuestionTag(questionBanks.getListQuestionTag());
            }

            //解析处理
            questionMapper.deleteQuestionExplain(questionId);
            if (null != questionBanks.getQuestionExplain()) {
                List<QuestionExplain> questionExplainList = new ArrayList<>();
                questionBanks.getQuestionExplain().setQbankId(questionId);
                questionExplainList.add(questionBanks.getQuestionExplain());
                questionMapper.batchSaveQuestionExplain(questionExplainList);
            }
        }

        //剩下的就是之前选择了修改的时候删掉的
        for (Integer qid : qids) {
            //添加的时候选择了，修改的时候未勾选，需要删除
            logger.info("添加的时候选择了，修改的时候未勾选，需要删除：qid=" + qid);
            questionMapper.deleteByQuestionId(qid);
        }

        return questionBanksList.get(questionBanksList.size() - 1).getId();
    }

    @Transactional
    @Override
    public boolean updateQuestionBank(QuestionBanks questionBanks) {
        int count = questionMapper.updateQuestionBank(questionBanks);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public List<QuestionBanksImg> selectQuestionBanksImgByQuestionId(Integer qbankId) {
        List<QuestionBanksImg> questionBanksImgList = new ArrayList<>();
        try {
            questionBanksImgList = questionMapper.selectQuestionBanksImgByQuestionId(qbankId);
        } catch (Exception e) {
            logger.error("系统异常：" + e.getMessage());
        }
        return questionBanksImgList;
    }

    @Transactional
    @Override
    public boolean deleteQuestionBanksImg(Integer qbankId) {
        questionMapper.deleteQuestionBanksImg(qbankId);
        return true;
    }

    @Transactional
    @Override
    public boolean saveQuestionImg(QuestionBanksImg questionBanksImg) {
        int count = questionMapper.saveQuestionImg(questionBanksImg);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public boolean batchSaveQuestionImg(List<QuestionBanksImg> questionBanksImgList) {
        int count = questionMapper.batchSaveQuestionImg(questionBanksImgList);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public List<QuestionOptionAnswer> selectQuestionOptionAnswerByQuestionId(Integer qbankId) {
        List<QuestionOptionAnswer> questionOptionAnswerList = new ArrayList<>();
        try {
            questionOptionAnswerList = questionMapper.selectQuestionOptionAnswerByQuestionId(qbankId);
        } catch (Exception e) {
            logger.error("系统异常" + e.getMessage());
        }
        return questionOptionAnswerList;
    }

    @Transactional
    @Override
    public boolean deleteQuestionOptionAnswer(Integer qbankId) {
        questionMapper.deleteQuestionOptionAnswer(qbankId);
        return true;
    }

    @Transactional
    @Override
    public boolean saveQuestionOptionAnswer(QuestionOptionAnswer questionOptionAnswer) {
        int count = questionMapper.saveQuestionOptionAnswer(questionOptionAnswer);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public boolean batchSaveQuestionOptionAnswer(List<QuestionOptionAnswer> questionOptionAnswerList) {
        int count = questionMapper.batchSaveQuestionOptionAnswer(questionOptionAnswerList);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public List<QuestionRightAnswer> selectQuestionRightAnswerByQuestionId(Integer qbankId) {
        List<QuestionRightAnswer> questionRightAnswerList = new ArrayList<>();
        try {
            questionRightAnswerList = questionMapper.selectQuestionRightAnswerByQuestionId(qbankId);
        } catch (Exception e) {
            logger.error("系统异常" + e.getMessage());
        }
        return questionRightAnswerList;
    }

    @Transactional
    @Override
    public boolean deleteQuestionRightAnswer(Integer qbankId) {
        questionMapper.deleteQuestionRightAnswer(qbankId);
        return true;
    }

    @Transactional
    @Override
    public boolean saveQuestionRightAnswer(QuestionRightAnswer questionRightAnswer) {
        int count = questionMapper.saveQuestionRightAnswer(questionRightAnswer);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public boolean batchSaveQuestionRightAnswer(List<QuestionRightAnswer> questionRightAnswerList) {
        int count = questionMapper.batchSaveQuestionRightAnswer(questionRightAnswerList);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public List<Map<String, Object>> selectQuestionsByIds(String questionIds) {
        return questionMapper.selectQuestionsByIds(questionIds);
    }

    @Override
    public List<KnowledgePointMistakes> selectKnowledgePointMistakes() {
        List<KnowledgePointMistakes> resultList = questionMapper.selectKnowlwdgePointMistakes();

        List<KnowledgePointMistakes> detailedList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(resultList)) {
            for (KnowledgePointMistakes item : resultList) {
                if (null != item) {
                    KnowledgePointMistakes detailedItem = item;
                    detailedItem.setListChildKnowledgePointMistakes(questionMapper.selectChildKnowledgePointMistakes(item.getId()));
                    detailedList.add(detailedItem);
                }
            }
        }
        return detailedList;
    }

    @Override
    public List<KnowledgePointMistakes> selectChildKnowledgePointMistakes(Integer parentId) {
        return questionMapper.selectChildKnowledgePointMistakes(parentId);
    }

    @Override
    public Stack<Integer> getFirstKnnowledgePointMistakesId(Integer id, Stack<Integer> selectedIdsStack) {
        if (null == selectedIdsStack) {
            selectedIdsStack = new Stack<>();
        }
        Map<String, Integer> resultMap = questionMapper.selectParentKnowledgePointMistakes(id);
        Integer parentId = resultMap.get("parentId");
        Integer cid = resultMap.get("id");
        selectedIdsStack.push(cid);
        if (parentId == 0) {
            return selectedIdsStack;
        } else {
            return getFirstKnnowledgePointMistakesId(parentId, selectedIdsStack);
        }
    }

    @Override
    public List<QuestionTerm> selectQuestionTermByGradeId(Integer qgradeId) {
        List<QuestionTerm> questionTermList = new ArrayList<>();
        try {
            questionTermList = questionMapper.selectQuestionTermByGradeId(qgradeId);
        } catch (Exception e) {
            logger.error("系统异常" + e.getMessage());
        }
        return questionTermList;
    }

    @Override
    public List<QuestionTerm> selectQuestionTermByParentTermId(Integer parentTermId) {
        List<QuestionTerm> questionTermList = new ArrayList<>();
        try {
            questionTermList = questionMapper.selectQuestionTermByParentId(parentTermId);
        } catch (Exception e) {
            logger.error("系统异常" + e.getMessage());
        }
        return questionTermList;
    }

    @Override
    public PageInfo<QuestionKnowledge> selectQKnowledgeList(String search, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<QuestionKnowledge> list = questionMapper.selectQKnowledgeList(search);
        // 分页信息
        PageInfo<QuestionKnowledge> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        pageNum = pageInfo.getPageNum();
        pageSize = pageInfo.getPageSize();
        logger.info("分页信息：total=" + total + "，pages=" + pages + "，pageNum=" + pageNum + "，pageSize=" + pageSize
                + "，搜索关键字：search=" + search);
        return pageInfo;
    }

    @Override
    public QuestionKnowledge selectQKnowledgeById(Integer knowledgeId) {
        return questionMapper.selectQKnowledgeById(knowledgeId);
    }

    @Override
    public QuestionKnowledge selectQKnowledgeWithKpById(Integer knowledgeId) {
        return questionMapper.selectQKnowledgeWithKpById(knowledgeId);
    }

    @Transactional
    @Override
    public boolean saveQKnowledge(QuestionKnowledge knowledge, String recorder) {
        knowledge.setRecorder(recorder);
        int count = questionMapper.saveQKnowledge(knowledge);
        if (count > 0) {
            //添加知识点教材页码关联
            List<Map> textbooksList = knowledge.getTextbooksList();
            if (!CollectionUtils.isEmpty(textbooksList)) {
                for (Map map : textbooksList) {
                    map.put("qknowledgeId", knowledge.getId());
                    map.put("recorder", recorder);
                }
                textBooksMapper.batchSaveTextbooksKnowledge(textbooksList);
            }
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public boolean editQKnowledge(QuestionKnowledge knowledge, String recorder) {
        int count = questionMapper.editQKnowledge(knowledge);
        if (count > 0) {
            List<Map> textbooksList = knowledge.getTextbooksList();

            if (!CollectionUtils.isEmpty(textbooksList)) {
                //修改知识点教材页码关联
                if (knowledge.getIsContinueAdd() == null || knowledge.getIsContinueAdd() == 0) {
                    // 修改先删除旧数据，继续录入不删除
                    textBooksMapper.deleteRelatedTextbooksByKnowledgeId(knowledge.getId());
                }
                for (Map map : textbooksList) {
                    map.put("recorder", recorder);
                }
                textBooksMapper.batchSaveTextbooksKnowledge(textbooksList);
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean checkKnowledgeExist(String cnName) {
        int count = questionMapper.checkKnowledgeExist(cnName);
        if (count > 0) {
            return false;
        }
        return true;
    }

    @Override
    public boolean checkOtherKnowledgeExist(String oldCnName, String newCnName) {
        int count = questionMapper.checkOtherKnowledgeExist(oldCnName, newCnName);
        if (count > 0) {
            return false;
        }
        return true;
    }

    @Transactional
    @Override
    public boolean delKnowledgeById(Integer id) {
        int count = questionMapper.delKnowledgeById(id);
        if (count > 0) {
            // 删除教材知识点关联
            questionMapper.delTextbooksKnowledgeById(id);
            return true;
        }
        return false;
    }

    @Override
    public PageInfo<QuestionBanks> getQuestionListByKnowledgeId(Integer knowledgeId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<QuestionBanks> list = questionMapper.getQuestionListByKnowledgeId(knowledgeId);
        // 分页信息
        PageInfo<QuestionBanks> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        pageNum = pageInfo.getPageNum();
        pageSize = pageInfo.getPageSize();
        logger.info("分页信息：total=" + total + "，pages=" + pages + "，pageNum=" + pageNum + "，pageSize=" + pageSize);
        return pageInfo;
    }

    @Override
    public PageInfo<QuestionBanks> getQuestionListByQuestionIdList(List<String> questionIdList, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<QuestionBanks> list = questionMapper.getQuestionListByQuestionIdList(questionIdList);
        // 分页信息
        PageInfo<QuestionBanks> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        pageNum = pageInfo.getPageNum();
        pageSize = pageInfo.getPageSize();
        logger.info("分页信息：total=" + total + "，pages=" + pages + "，pageNum=" + pageNum + "，pageSize=" + pageSize);
        return pageInfo;
    }

    @Override
    public PageInfo getKnowledgeListByQuestionId(Integer qbankId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<QuestionKnowledge> list = questionMapper.getKnowledgeListByQuestionId(qbankId);
        // 分页信息
        PageInfo<QuestionKnowledge> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        pageNum = pageInfo.getPageNum();
        pageSize = pageInfo.getPageSize();
        logger.info("分页信息：total=" + total + "，pages=" + pages + "，pageNum=" + pageNum + "，pageSize=" + pageSize);
        return pageInfo;
    }

    @Override
    public PageInfo getKnowledgeListByKnowledgeIdList(List<String> knowledgeList, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<QuestionKnowledge> list = questionMapper.getKnowledgeListByKnowledgeIdList(knowledgeList);
        // 分页信息
        PageInfo<QuestionKnowledge> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        pageNum = pageInfo.getPageNum();
        pageSize = pageInfo.getPageSize();
        logger.info("分页信息：total=" + total + "，pages=" + pages + "，pageNum=" + pageNum + "，pageSize=" + pageSize);
        return pageInfo;
    }

    @Override
    public List<QuestionKnowledge> getKnowledgeListByMistakeId(Integer mistakeId) {
        return questionMapper.getKnowledgeListByMistakeId(mistakeId);
    }

    @Override
    public boolean checkKnowKpPrimiaryKey(Map pkMap) {
        int count = questionMapper.checkKnowKpPrimiaryKey(pkMap);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean checkKnowledgeExistById(Integer id) {
        int count = questionMapper.checkKnowledgeExistById(id);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Transactional
    @Override
    public Map batchImport(String fileName, MultipartFile mfile, HttpSession session) {
        Map resultMap = new HashMap();
        int errorLine = 1;
        InputStream is = null;
        Map<String, Object> cacheMap = new HashMap<>();
        Map<String, Object> knowStateMap = new HashMap<>();
        try {
            is = mfile.getInputStream();

            Workbook workbook = null;
            //根据版本选择创建Workbook的方式
            //根据文件名判断文件是2003版本还是2007版本
            Sheet sheet = null;
            if (ExcelImportUtils.isExcel2007(fileName)) {
                // 针对2007 Excel 文件
                workbook = new XSSFWorkbook(is);
                sheet = workbook.getSheetAt(0);
            } else {
                // 针对 2003 Excel 文件
                workbook = new HSSFWorkbook(new POIFSFileSystem(is));
                sheet = workbook.getSheetAt(0);
            }
            int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
            // 总共的数据
            List<Map> dataList = new ArrayList<>();
            for (int i = 0; i < physicalNumberOfRows; i++) {
                errorLine = (i + 1);
                if (i == 0 || i == 1) {
                    continue;//标题行
                }
                Row row = sheet.getRow(i);
                // 第2列是知识点名称
                String knowledgeName = getCellFromRow(row, 1, false);
                // 第3列是教材ID
                String textbooksId = getCellFromRow(row, 2, false);
                // 第4列是知识点ID
                String qkId = getCellFromRow(row, 3, false);
                // 第5列是页码
                String pageName = getCellFromRow(row, 4, false);
                // 第6列是考点ID
                String kpId = getCellFromRow(row, 5, false);
                // 第7列是考点名称
                String kpName = getCellFromRow(row, 6, false);
                // 第8列是二级考点ID
                String kpSecond = getCellFromRow(row, 7, false);
                // 第9列是三级考点ID
                String kpThird = getCellFromRow(row, 8, false);

                // 校验行
                if (StringUtils.isNotEmpty(knowledgeName)
                        && StringUtils.isNotEmpty(textbooksId)
                        && StringUtils.isNotEmpty(pageName)
                        && StringUtils.isNotEmpty(kpId)
                        && StringUtils.isNotEmpty(kpName)
                ) {
                    // ========================================
                    // 设置知识点
                    boolean needInsert = false;
                    // 如果没有填写知识点ID，则需要根据名称查找或者新增知识点
                    String dbQkId = String.valueOf(questionMapper.selectIdByKnowledgeName(knowledgeName));
                    if (StringUtils.isEmpty(qkId) || !qkId.equals(dbQkId)) {
                        // 先根据知识点名称查找
                        qkId = dbQkId.equals("null") ? qkId : dbQkId;
                        if (null == qkId) {
                            needInsert = true;
                        }
                    }
                    // 如果该知识点已经删除，需要重新插入
                    if (knowStateMap.containsKey(qkId)) {
                        String newQkId = (String) knowStateMap.getOrDefault(qkId, "0");
                        if (Integer.parseInt(newQkId) > 0) {
                            needInsert = false;
                            qkId = newQkId;
                        }
                    } else {
                        if (StringUtils.isNotEmpty(qkId)) {
                            needInsert = !checkKnowledgeExistById(Integer.parseInt(qkId));
                        }
                    }
                    // 满足插入知识点的条件
                    if (needInsert) {
                        String oldQkId = qkId;
                        // 插入知识点
                        logger.debug("插入知识点" + knowledgeName);
                        QuestionKnowledge questionKnowledge = new QuestionKnowledge();
                        questionKnowledge.setCnName(knowledgeName);
                        questionMapper.saveQKnowledge(questionKnowledge);
                        qkId = String.valueOf(questionKnowledge.getId());
                        // 一个知识点只插入一次
                        knowStateMap.put(oldQkId, qkId);
                    }

                    // ===================================
                    // 设置页码以及索引
                    // 查找页码配置文件
                    // 查找页码索引
                    JSONArray ja = null;
                    int pageIdx = 0;
                    if (cacheMap.get(textbooksId) == null) {
                        ja = textbooksService.getConfigByTextbooksId(Integer.parseInt(textbooksId));
                        cacheMap.put(textbooksId, ja);
                        logger.debug("保存配置文件");
                    } else {
                        ja = (JSONArray) cacheMap.get(textbooksId);
                        logger.debug("从缓存获取配置文件");
                    }
                    pageIdx = textbooksService.getTextbooksIdxByPage(ja, pageName);
                    if (pageIdx == -1) {
                        logger.error("教材页码索引错误=>" + pageName + "获取到得页码索引是" + pageIdx);
                    }

                    // =========================================
                    // 设置考点ID,先取三级再取二级，最后取一级
                    int kpMistakesId = 0;
                    if (StringUtils.isNotEmpty(kpThird)) {
                        kpMistakesId = Integer.parseInt(kpThird);
                    } else if (StringUtils.isNotEmpty(kpSecond)) {
                        kpMistakesId = Integer.parseInt(kpSecond);
                    } else {
                        kpMistakesId = Integer.parseInt(kpId);
                    }

                    // 设置每一行数据
                    Map itemMap = new HashMap();
                    // 返回主键ID
                    itemMap.put("qknowledgeId", qkId);
                    itemMap.put("textbooksId", textbooksId);
                    itemMap.put("textbooksPage", pageIdx);
                    itemMap.put("textbooksPageName", pageName);
                    itemMap.put("knowledgePoint", kpMistakesId);
                    String recorder = (String) session.getAttribute("loginname");
                    itemMap.put("recorder", recorder);

                    dataList.add(itemMap);

                    logger.debug("读取第" + errorLine + "行,data:" + JSON.toJSONString(dataList));
                } else {
                    logger.error("导入出错！第" + errorLine + "行数据为空");
                }
            }

            // Excel数据检查
            if (CollectionUtils.isEmpty(dataList)) {
                // 异常手动回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                logger.error("导入出错！筛选前可导入数据为空");
                resultMap.put("status", 0);
                resultMap.put("msg", "导入出错！筛选前可导入数据为空");
                return resultMap;
            }

            // 批量插入知识点教材页码管理
            List<Map> notImportedList = textbooksService.getNotImportedList(dataList);
            if (CollectionUtils.isEmpty(notImportedList)) {
                // 异常手动回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                logger.error("导入出错！筛选后可导入数据为空");
                resultMap.put("status", 0);
                resultMap.put("msg", "导入出错！筛选后可导入数据为空");
                return resultMap;
            }

            logger.info("插入的数据量：" + notImportedList.size());
            List importKnowledgeList = notImportedList.stream().map(x -> x.get("qknowledgeId")).collect(toList());
            int importKnowledgeCount = ((List) importKnowledgeList.stream().distinct().map(x -> Object.class.cast(x)).collect(toList())).size();
            logger.info("导入的知识点数目：" + importKnowledgeCount);

            //开始导入
            logger.info("notImportedList:", JSON.toJSONString(notImportedList));
            textBooksMapper.batchSaveTextbooksKnowledge(notImportedList);

            resultMap.put("status", 1);
            resultMap.put("msg", "导入数据成功！" + ",共导入知识点数目：" + importKnowledgeCount + ",总共行数：" + errorLine + ",重复行数：" + (errorLine - importKnowledgeCount));
        } catch (Exception e) {
            // 异常手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("Excel import error:" + e.getMessage(), e);
            resultMap.put("status", 0);
            resultMap.put("msg", "导入出错！请检查数据格式！" + e.getMessage());
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    is = null;
                    logger.error("Excel import error:" + e.getMessage(), e);
                }
            }
        }
        return resultMap;
    }

    /**
     * 读取某一行中的特定列
     *
     * @param row       行
     * @param cellIndex 列索引
     * @return 列
     */
    private String getCellFromRow(Row row, Integer cellIndex, boolean isReplaceSplit) {
        if (row.getCell(cellIndex) != null) {
            // 知识点名称
            row.getCell(cellIndex).setCellType(CELL_TYPE_STRING);
            Cell cell = row.getCell(cellIndex);
            String cellValue = getCellValue(cell, isReplaceSplit);
            return cellValue;
        }
        return null;
    }

    /**
     * 将cell格式转换成String
     *
     * @param cell           cell
     * @param isReplaceSplit 是否替换
     * @return cell的值
     */
    private String getCellValue(Cell cell, boolean isReplaceSplit) {
        String cellValue = "";
        switch (cell.getCellType()) {
            case CELL_TYPE_STRING:
                cellValue = cell.getRichStringCellValue().getString().trim();
                break;
            case CELL_TYPE_NUMERIC:
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case CELL_TYPE_BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
                break;
            case CELL_TYPE_FORMULA:
                cellValue = cell.getCellFormula();
                break;
            default:
                cellValue = "";
        }
        // 格式转换
        cellValue = cellValue.trim().toLowerCase();
        if (isReplaceSplit) {
            cellValue = cellValue.replace("，", ",").replace(".", ",").replace("。", ",");
        }
        return cellValue;
    }

    @Override
    public String getKpNameById(Integer kpId) {
        return questionMapper.getKpNameById(kpId);
    }
}
